home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / cagd_lib / cagdcmpt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  9.3 KB  |  293 lines

  1. /******************************************************************************
  2. * CagdCmpt.c - Make objects compatible.                          *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 91.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. /******************************************************************************
  10. * Given two curves, make the compatible by:                      *
  11. * 1. Coercing their point type to be the same.                      *
  12. * 2. Make them have the same curve type.                      *
  13. * 3. Raising the degree of the lower one to be the same.              *
  14. * 4. Refine them to a common knot vector (If Bspline).                  *
  15. * Note 3 is preformed if SameOrder TRUE, 4 if SameKV TRUE.              *
  16. * Returns TRUE if succesfull. Both Curves are modified IN PLACE.          *
  17. ******************************************************************************/
  18. CagdBType CagdMakeCrvsCompatible(CagdCrvStruct **Crv1, CagdCrvStruct **Crv2,
  19.                  CagdBType SameOrder, CagdBType SameKV)
  20. {
  21.     int KV1Len, KV2Len, RefLen;
  22.     CagdRType *KV1, *KV2, *RefKV;
  23.     CagdCrvStruct *TCrv;
  24.     CagdPointType CommonPType;
  25.  
  26.     if ((*Crv1 == NULL) || (*Crv2 == NULL))
  27.     return TRUE;
  28.  
  29.     CommonPType = CagdMergePointType((*Crv1) -> PType, (*Crv2) -> PType);
  30.  
  31.     /* Make the point types compatible. */
  32.     if (CommonPType != (*Crv1) -> PType) {
  33.     TCrv = CagdCoerceCrvTo(*Crv1, CommonPType);
  34.     CagdCrvFree(*Crv1);
  35.     *Crv1 = TCrv;
  36.     }
  37.     if (CommonPType != (*Crv2) -> PType) {
  38.     TCrv = CagdCoerceCrvTo(*Crv2, CommonPType);
  39.     CagdCrvFree(*Crv2);
  40.     *Crv2 = TCrv;
  41.     }
  42.  
  43.     if (SameOrder) {
  44.     /* Raise the degree of the lower one. */
  45.     if ((*Crv1) -> Order < (*Crv2) -> Order) {
  46.         TCrv = CagdCrvDegreeRaiseN(*Crv1, (*Crv2) -> Order);
  47.         CagdCrvFree(*Crv1);
  48.         *Crv1 = TCrv;
  49.     }
  50.     else if ((*Crv2) -> Order < (*Crv1) -> Order) {
  51.         TCrv = CagdCrvDegreeRaiseN(*Crv2, (*Crv1) -> Order);
  52.         CagdCrvFree(*Crv2);
  53.         *Crv2 = TCrv;
  54.     }
  55.     }
  56.  
  57.     /* If incompatible curve type - make it the same as well. */
  58.     if ((*Crv1) -> GType != (*Crv2) -> GType) {
  59.     /* If power basis - promote to bezier: */
  60.     if ((*Crv1) -> GType == CAGD_CPOWER_TYPE) {
  61.         TCrv = CnvrtPower2BezierCrv(*Crv1);
  62.         CagdCrvFree(*Crv1);
  63.         *Crv1 = TCrv;
  64.     }
  65.     if ((*Crv2) -> GType == CAGD_CPOWER_TYPE) {
  66.         TCrv = CnvrtPower2BezierCrv(*Crv2);
  67.         CagdCrvFree(*Crv2);
  68.         *Crv2 = TCrv;
  69.     }
  70.  
  71.     /* Now both curves may be either bezier or bspline curves. */
  72.     if ((*Crv1) -> GType != (*Crv2) -> GType) {
  73.         /* If bezier basis - promote to bspline: */
  74.         if ((*Crv1) -> GType == CAGD_CBEZIER_TYPE) {
  75.         TCrv = CnvrtBezier2BsplineCrv(*Crv1);
  76.         CagdCrvFree(*Crv1);
  77.         *Crv1 = TCrv;
  78.         }
  79.         if ((*Crv2) -> GType == CAGD_CBEZIER_TYPE) {
  80.         TCrv = CnvrtBezier2BsplineCrv(*Crv2);
  81.         CagdCrvFree(*Crv2);
  82.         *Crv2 = TCrv;
  83.         }
  84.     }
  85.     }
  86.  
  87.     if (SameKV) {
  88.     /* If bspline curve - make sure knot vectors are the same. */
  89.     if ((*Crv1) -> GType == CAGD_CBSPLINE_TYPE) {
  90.         KV1 = (*Crv1) -> KnotVector;
  91.         KV2 = (*Crv2) -> KnotVector;
  92.         KV1Len = (*Crv1) -> Length + (*Crv1) -> Order;
  93.         KV2Len = (*Crv2) -> Length + (*Crv2) -> Order;
  94.  
  95.         /* Affine map second knot vector to span same parametric domain. */
  96.         BspKnotAffineTrans(KV2, KV2Len, KV1[0] - KV2[0],
  97.                    (KV1[KV1Len - 1] - KV1[0]) /
  98.                    (KV2[KV2Len - 1] - KV2[0]));
  99.  
  100.         /* Find knots in KV2 which are not in KV1 and refine Crv1 there. */
  101.         RefKV  = BspKnotSubtrTwo(KV2, KV2Len, KV1, KV1Len, &RefLen);
  102.         if (RefLen > 0) {
  103.         TCrv = CagdCrvRefineAtParams(*Crv1, FALSE, RefKV, RefLen);
  104.         CagdCrvFree(*Crv1);
  105.         *Crv1 = TCrv;
  106.         KV1 = (*Crv1) -> KnotVector;
  107.         KV1Len = (*Crv1) -> Length + (*Crv1) -> Order;
  108.         }
  109.         IritFree((VoidPtr) RefKV);
  110.  
  111.         /* Find knots in KV1 which are not in KV2 and refine Crv2 there. */
  112.         RefKV  = BspKnotSubtrTwo(KV1, KV1Len, KV2, KV2Len, &RefLen);
  113.         if (RefLen > 0) {
  114.         TCrv = CagdCrvRefineAtParams(*Crv2, FALSE, RefKV, RefLen);
  115.         CagdCrvFree(*Crv2);
  116.         *Crv2 = TCrv;
  117.         }
  118.         IritFree((VoidPtr) RefKV);
  119.     }
  120.     }
  121.  
  122.     return TRUE;
  123. }
  124.  
  125. /******************************************************************************
  126. * Given two surfaces, make the compatible by:                      *
  127. * 1. Coercing their point type to be the same.                      *
  128. * 2. Make them have the same surface type.                      *
  129. * 3. Raising the degree of the lower one to be the same.              *
  130. * 4. Refine them to common knot vectors (If Bspline).                  *
  131. * Note 3 is preformed if SameOrder TRUE, 4 if SameKV TRUE.              *
  132. * Returns TRUE if succesfull. Both Surfaces are modified IN PLACE.          *
  133. ******************************************************************************/
  134. CagdBType CagdMakeSrfsCompatible(CagdSrfStruct **Srf1, CagdSrfStruct **Srf2,
  135.                  CagdBType SameUOrder, CagdBType SameVOrder,
  136.                  CagdBType SameUKV, CagdBType SameVKV)
  137. {
  138.     int i, KV1Len, KV2Len, RefLen;
  139.     CagdRType *KV1, *KV2, *RefKV;
  140.     CagdSrfStruct *TSrf;
  141.     CagdPointType CommonPType;
  142.  
  143.     if ((*Srf1 == NULL) || (*Srf2 == NULL))
  144.     return TRUE;
  145.  
  146.     CommonPType = CagdMergePointType((*Srf1) -> PType, (*Srf2) -> PType);
  147.  
  148.     /* Make the point types compatible. */
  149.     if (CommonPType != (*Srf1) -> PType) {
  150.     TSrf = CagdCoerceSrfTo(*Srf1, CommonPType);
  151.     CagdSrfFree(*Srf1);
  152.     *Srf1 = TSrf;
  153.     }
  154.     if (CommonPType != (*Srf2) -> PType) {
  155.     TSrf = CagdCoerceSrfTo(*Srf2, CommonPType);
  156.     CagdSrfFree(*Srf2);
  157.     *Srf2 = TSrf;
  158.     }
  159.  
  160.     if (SameUOrder) {
  161.     /* Raise the degree of the lower one. */
  162.     for (i = (*Srf1) -> UOrder; i < (*Srf2) -> UOrder; i++) {
  163.         TSrf = CagdSrfDegreeRaise(*Srf1, CAGD_CONST_V_DIR);
  164.         CagdSrfFree(*Srf1);
  165.         *Srf1 = TSrf;
  166.     }
  167.     for (i = (*Srf2) -> UOrder; i < (*Srf1) -> UOrder; i++) {
  168.         TSrf = CagdSrfDegreeRaise(*Srf2, CAGD_CONST_V_DIR);
  169.         CagdSrfFree(*Srf2);
  170.         *Srf2 = TSrf;
  171.     }
  172.     }
  173.     if (SameVOrder) {
  174.     for (i = (*Srf1) -> VOrder; i < (*Srf2) -> VOrder; i++) {
  175.         TSrf = CagdSrfDegreeRaise(*Srf1, CAGD_CONST_U_DIR);
  176.         CagdSrfFree(*Srf1);
  177.         *Srf1 = TSrf;
  178.     }
  179.     for (i = (*Srf2) -> VOrder; i < (*Srf1) -> VOrder; i++) {
  180.         TSrf = CagdSrfDegreeRaise(*Srf2, CAGD_CONST_U_DIR);
  181.         CagdSrfFree(*Srf2);
  182.         *Srf2 = TSrf;
  183.     }
  184.     }
  185.  
  186.     /* If incompatible surface type - make it the same as well. */
  187.     if ((*Srf1) -> GType != (*Srf2) -> GType) {
  188.     /* If power basis - promote to bezier: */
  189.     if ((*Srf1) -> GType == CAGD_SPOWER_TYPE) {
  190.         TSrf = CnvrtPower2BezierSrf(*Srf1);
  191.         CagdSrfFree(*Srf1);
  192.         *Srf1 = TSrf;
  193.     }
  194.     if ((*Srf2) -> GType == CAGD_SPOWER_TYPE) {
  195.         TSrf = CnvrtPower2BezierSrf(*Srf2);
  196.         CagdSrfFree(*Srf2);
  197.         *Srf2 = TSrf;
  198.     }
  199.  
  200.     /* Now both surfaces may be either bezier or bspline surfaces. */
  201.     if ((*Srf1) -> GType != (*Srf2) -> GType) {
  202.         /* If bezier basis - promote to bspline: */
  203.         if ((*Srf1) -> GType == CAGD_SBEZIER_TYPE) {
  204.         TSrf = CnvrtBezier2BsplineSrf(*Srf1);
  205.         CagdSrfFree(*Srf1);
  206.         *Srf1 = TSrf;
  207.         }
  208.         if ((*Srf2) -> GType == CAGD_SBEZIER_TYPE) {
  209.         TSrf = CnvrtBezier2BsplineSrf(*Srf2);
  210.         CagdSrfFree(*Srf2);
  211.         *Srf2 = TSrf;
  212.         }
  213.     }
  214.     }
  215.  
  216.     if ((*Srf1) -> GType == CAGD_SBSPLINE_TYPE) {
  217.     /* If bspline surface - make sure knot vectors are the same. */
  218.  
  219.     if (SameUKV) {
  220.         /* Handle the U Direction. */
  221.         KV1 = (*Srf1) -> UKnotVector;
  222.         KV2 = (*Srf2) -> UKnotVector;
  223.         KV1Len = (*Srf1) -> ULength + (*Srf1) -> UOrder;
  224.         KV2Len = (*Srf2) -> ULength + (*Srf2) -> UOrder;
  225.  
  226.         /* Affine map second knot vector to span same parametric domain. */
  227.         BspKnotAffineTrans(KV2, KV2Len, KV1[0] - KV2[0],
  228.                    (KV1[KV1Len - 1] - KV1[0]) /
  229.                    (KV2[KV2Len - 1] - KV2[0]));
  230.  
  231.         /* Find knots in KV2 which are not in KV1 and refine Srf1 there. */
  232.         RefKV  = BspKnotSubtrTwo(KV2, KV2Len, KV1, KV1Len, &RefLen);
  233.         if (RefLen > 0) {
  234.         TSrf = CagdSrfRefineAtParams(*Srf1, CAGD_CONST_U_DIR,
  235.                          FALSE, RefKV, RefLen);
  236.         CagdSrfFree(*Srf1);
  237.         *Srf1 = TSrf;
  238.         KV1 = (*Srf1) -> UKnotVector;
  239.         KV1Len = (*Srf1) -> ULength + (*Srf1) -> UOrder;
  240.         }
  241.         IritFree((VoidPtr) RefKV);
  242.  
  243.         /* Find knots in KV1 which are not in KV2 and refine Srf2 there. */
  244.         RefKV  = BspKnotSubtrTwo(KV1, KV1Len, KV2, KV2Len, &RefLen);
  245.         if (RefLen > 0) {
  246.         TSrf = CagdSrfRefineAtParams(*Srf2, CAGD_CONST_U_DIR,
  247.                          FALSE, RefKV, RefLen);
  248.         CagdSrfFree(*Srf2);
  249.         *Srf2 = TSrf;
  250.         }
  251.         IritFree((VoidPtr) RefKV);
  252.     }
  253.  
  254.     if (SameVKV) {
  255.         /* Handle the V Direction. */
  256.         KV1 = (*Srf1) -> VKnotVector;
  257.         KV2 = (*Srf2) -> VKnotVector;
  258.         KV1Len = (*Srf1) -> VLength + (*Srf1) -> VOrder;
  259.         KV2Len = (*Srf2) -> VLength + (*Srf2) -> VOrder;
  260.  
  261.         /* Affine map second knot vector to span same parametric domain. */
  262.         BspKnotAffineTrans(KV2, KV2Len, KV1[0] - KV2[0],
  263.                    (KV1[KV1Len - 1] - KV1[0]) /
  264.                    (KV2[KV2Len - 1] - KV2[0]));
  265.  
  266.         /* Find knots in KV2 which are not in KV1 and refine Srf1 there. */
  267.         RefKV  = BspKnotSubtrTwo(KV2, KV2Len, KV1, KV1Len, &RefLen);
  268.         if (RefLen > 0) {
  269.         TSrf = CagdSrfRefineAtParams(*Srf1, CAGD_CONST_V_DIR,
  270.                          FALSE, RefKV, RefLen);
  271.         CagdSrfFree(*Srf1);
  272.         *Srf1 = TSrf;
  273.         KV1 = (*Srf1) -> VKnotVector;
  274.         KV1Len = (*Srf1) -> VLength + (*Srf1) -> VOrder;
  275.         }
  276.         IritFree((VoidPtr) RefKV);
  277.  
  278.         /* Find knots in KV1 which are not in KV2 and refine Srf2 there. */
  279.         RefKV  = BspKnotSubtrTwo(KV1, KV1Len, KV2, KV2Len, &RefLen);
  280.         if (RefLen > 0) {
  281.         TSrf = CagdSrfRefineAtParams(*Srf2, CAGD_CONST_V_DIR,
  282.                          FALSE, RefKV, RefLen);
  283.         CagdSrfFree(*Srf2);
  284.         *Srf2 = TSrf;
  285.         }
  286.         IritFree((VoidPtr) RefKV);
  287.     }
  288.     }
  289.  
  290.     return TRUE;
  291. }
  292.  
  293.